#ifndef SCT_MUX_TSHEAD_H
#define SCT_MUX_TSHEAD_H

#include "sct/core/common.h"

namespace sct
{

/**
* @see ISO/IEC 13818-1 Information technology  Generic codingof moving pictures and associated audioinformation: Systems
*/

enum MpegTsPid
{
    MpegTsPidPAT = 0x00,

    MpegTsPiddCAT = 0x01,

    MpegTsPidTSDT = 0x02,

    MpegTsPidReservedStart = 0x03,
    MpegTsPidReservedEnd = 0x0f,

    MpegTsPidAppStart = 0x10,
    MpegTsPidAppEnd = 0x1ffe,

    MpegTsPidNULL = 0x01FFF,
};

enum MpegTsAdaptationFieldType
{
    // Reserved for future use by ISO/IEC
    MpegTsAdaptationFieldTypeReserved = 0x00,
    // No adaptation_field, payload only
    MpegTsAdaptationFieldTypePayloadOnly = 0x01,
    // Adaptation_field only, no payload
    MpegTsAdaptationFieldTypeAdaptionOnly = 0x02,
    // Adaptation_field followed by payload
    MpegTsAdaptationFieldTypeBoth = 0x03,
};

enum MpegTsStream
{
    MpegTsStreamAudioAAC = 0x0f,

    MpegTsStreamVideoMpeg4 = 0x10,

    MpegTsStreamAudioMpeg4 = 0x11,

    MpegTsStreamVideoAVC = 0x1b,
};

enum MpegTsPESStreamId
{
    MpegTsPESStreamIdAudioCommon = 0xc0,

    MpegTsPESStreamIdVideoCommon = 0xe0,
};

typedef struct {
    /*Btype 0 */
    unsigned char sync_byte:8;	/* Synchronization byte.         */
    /*Btype 1 */
    unsigned char pid_12to8:5;	/* Program ID, bits 12:8.        */
    unsigned char transport_priority:1;	/* TS Transport Priority.        */
    unsigned char payload_unit_start_indicator:1;	/* Payload Unit Start Indicator. */
    unsigned char transport_error_indicator:1;	/* TS Error Indicator.           */
    /*Btype 2 */
    unsigned char pid_7to0:8;	/* Program ID, bits 7:0.         */
    /*Btype 3 */
    unsigned char continuity_counter:4;	/* Countinuity counter.          */
    unsigned char adaptation_field_control:2;
    unsigned char transport_scrambling_control:2;	/* TS Scrambling Control.        */

} MPEGTS_HEADER_T;

/**
 * Adaptation field header.
 */
typedef struct {
    /*Byte 0 */
    unsigned char adaptation_field_length:8;	/* Adaptation field length, this field not included. */
    /*Byte 1 */
    unsigned char adaptation_field_extension_flag:1;	/* Adaptation field extension flag. */
    unsigned char transport_private_data_flag:1;	/* Transport private data flag. */
    unsigned char splicing_point_flag:1;	/* Splicing point flag. */
    unsigned char opcr_flag:1;	/* OPCR flag. */
    unsigned char pcr_flag:1;	/* PCR flag. */
    unsigned char elementary_stream_priority_indicator:1;	/* Elementary stream priority indicator */
    unsigned char random_access_indicator:1;	/* Random access indicator. */
    unsigned char discontinuity_indicator:1;	/* Discontinuity indicator. */
} MPEGTS_ADAPTATION_FIELD_HEADER_T;

/**
 * PES header.
 */
typedef struct {
    /*Byte 1 */
    unsigned char packet_start_code_23to16:8;	/* Packet start code. Bits 23:16.   */
    /*Byte 2 */
    unsigned char packet_start_code_15to8:8;	/* Packet start code. Bits 15:8.  */
    /*Byte 3 */
    unsigned char packet_start_code_7to0:8;	/* Packet start code. Bits 7:0. */
    /*Byte 4 */
    unsigned char stream_id:8;	/* Stream ID. */
    /*Byte 5 */
    unsigned char pes_packet_length_15to8:8;	/* Packet length. Bits 15:8. */
    /*Byte 6 */
    unsigned char pes_packet_length_7to0:8;	/* Packet length. Bits 7:0.  */
    /*Byte 7 */
    unsigned char original_or_copy:1;	/* Original or copy flag. */
    unsigned char copyright:1;	/* Copyright flag. */
    unsigned char data_alignment_indicator:1;	/* Data alignment control. */
    unsigned char pes_priority:1;	/* PES priority. */
    unsigned char pes_scrambling_control:2;	/* PES scrambling control. */
    unsigned char marker_bits:2;	/* Marker bits, the should be set to 0x02. */
    /*Byte 8 */
    unsigned char pes_ext_flag:1;	/* PES extension flag. */
    unsigned char pes_crc_flag:1;	/* PES CRC flag. */
    unsigned char add_copy_info_flag:1;	/* Additional copy info flag */
    unsigned char dsm_trick_mode_flag:1;	/* DSM trick mode flag. */
    unsigned char es_rate_flag:1;	/* Elementary stream flag. */
    unsigned char escr_flag:1;	/* ESCR flag. */
    unsigned char pts_dts_flags:2;	/* PTS/DTS flag. */
    /*Byte 9 */
    unsigned char header_data_length:8;	/* Length of optional fields and stuffing bytes. */

} MPEGTS_PES_HEADER_T;


typedef struct {
    /*Btype 0 */
    unsigned char table_id:8;
    /*Btype 1 */
    unsigned char section_length8to11:4;
    unsigned char reserved0:2;
    unsigned char b0:1;
    unsigned char section_syntax_indicator:1;
    /*Btype 2 */
    unsigned char section_length0to7:8;
    /*Btype 3 */
    unsigned char transport_stream_id_h:8;
    /*Btype 4 */
    unsigned char transport_stream_id_l:8;
    /*Btype 5 */
    unsigned char current_next_indicator:1;
    unsigned char version_number:5;
    unsigned char reserved1:2;
    /*Btype 6 */
    unsigned char section_number:8;
    /*Btype 7 */
    unsigned char last_section_number:8;
} MPEGTS_PAT_HEADER_T;

typedef struct {
    /*Btype 0 */
    unsigned char table_id:8;
    /*Btype 1 */
    unsigned char section_length8to11:4;
    unsigned char reserved0:2;
    unsigned char b0:1;
    unsigned char section_syntax_indicator:1;
    /*Btype 2 */
    unsigned char section_length0to7:8;
    /*Btype 3 */
    unsigned char program_number_h:8;
    /*Btype 4 */
    unsigned char program_number_l:8;
    /*Btype 5 */
    unsigned char current_next_indicator:1;
    unsigned char version_number:5;
    unsigned char reserved1:2;
    /*Btype 6 */
    unsigned char section_number:8;
    /*Btype 7 */
    unsigned char last_section_number:8;
    /*Btype 8 */
    unsigned char PCR_PID8to12:5;
    unsigned char reserved2:3;
    /*Btype 9 */
    unsigned char PCR_PID0to7:8;
    /*Btype 10 */
    unsigned char program_info_length8to11:4;
    unsigned char reserved3:4;
    /*Btype 11 */
    unsigned char program_info_length0to7:8;
} MPEGTS_PMT_HEADER_T;


typedef struct {
    /*Btype 0 */
    unsigned char stream_type:8;
    /*Btype 1 */
    unsigned char elementary_PID8to12:5;
    unsigned char reserved0:3;
    /*Btype 2 */
    unsigned char elementary_PID0to7:8;
    /*Btype 3 */
    unsigned char ES_info_length_h:4;
    unsigned char reserved1:4;
    /*Btype 4 */
    unsigned char ES_info_length_l:8;
} MPEGTS_PMT_ELEMENT_T;

typedef struct{
    unsigned long long pts;
    unsigned long long dts;
    unsigned int pid;
} MPEGTS_FRAME_T;

#define MPEGTS_PACKET_SIZE		188
#define MPEGTS_NULL_PACKET_PID	0x1FFF


/**
* calculate crc
* @param data, the data input for crc
* @param len, the length of data
* @return value of crc
*/
unsigned int getCrc32(const uint8_t *data, const int len);

}

#endif
